import { h, Fragment, isVNode, cloneVNode, defineComponent } from 'vue';
import BaseSystem from './system-base';
import { pickProps } from './utils';

const createElements = (elements, props) => {
  if (!elements || elements.length === 0) return null;
  if (!Array.isArray(elements)) return elements;
  return elements.map((item) => {
    if (isVNode(item)) return item;
    return h(item, props);
  });
};

const cloneChildren = (children, expose) => {
  if (!children) return;
  return children.map((child) => {
    if (isVNode(child)) {
      return cloneVNode(child, pickProps(expose, child.attrs || {}));
    }
    return child;
  });
};

class SystemVue3 extends BaseSystem {
  constructor(name, plugins) {
    super(name, plugins);
  }

  render(props, { slots, attrs }) {
    // const props = this.extendProps;
    const layoutContentKeys = this.layoutContentKeys;
    const collection = this.collection;

    // console.log('props::', props);

    const contentProps = { ...props, instance: this };

    const children = slots?.default?.();
    // 克隆组件传入的 children 列表
    const childrenNodes = cloneChildren(children, this.expose);

    // TODO 考虑换个名称，以防和其他自定义属性名冲突
    const contentRender = props.contentRender;

    // 创建插件内收集到组件和内容
    const nodes = layoutContentKeys.reduce((store, key) => {
      if (key === 'default') {
        let renderDefaultContent;
        if (contentRender === 'all') renderDefaultContent = collection.default;
        else if (contentRender === 'none') renderDefaultContent = [];
        else if (collection.default.length > 0 && contentRender > -1)
          renderDefaultContent = [collection.default?.[contentRender]];
        else if (collection.default.length > 0) renderDefaultContent = [collection.default?.[0]];

        store.default = () => [createElements(renderDefaultContent, {}), childrenNodes];
      } else {
        store[key] = () => createElements(collection[key], {});
      }
      return store;
    }, {});

    // console.log(nodes, collection, layoutContentKeys);

    return h(collection.layout || Fragment, { ...attrs, ...contentProps }, nodes);
  }

  build() {
    const instance = this;

    const PluginComponent = defineComponent({
      name: instance.name || 'PluginComponent',
      inheritAttrs: false,
      props: instance.props,
      setup(props, context) {
        // console.log(props, context);
        // 再次初始化，清空
        instance.init(props, context);
        // 预处理
        instance.before(props, context);
        // 主方法
        instance.main(props, context);
        // 暴露实例方法
        // expose(instance.expose);

        // 渲染
        return () => instance.render(props, context);
      },
    });
    return PluginComponent;
  }
}

export default SystemVue3;
